﻿#include <QDebug>
#include <QApplication>
#include <QDirIterator>
#include <ctkPluginContext.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>
#include <ctkPluginFrameworkFactory.h>
#include <ctkPluginFrameworkLauncher.h>
#include <QThread>
#include <qsettings.h>
#include <QTextCodec>
#include <log4qt/propertyconfigurator.h>
#include <log4qt/logmanager.h>
#include <log4qt/dailyrollingfileappender.h>
#include <log4qt/patternlayout.h>
#include <log4qt/logger.h>
#include <log4qt/consoleappender.h>
#include <service/pluginadmin/pluginAdmin.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QTextCodec *codec = QTextCodec::codecForName("utf8");
//    QTextCodec::setCodecForTr(codec);
    QTextCodec::setCodecForLocale(codec);
//    QTextCodec::setCodecForCStrings(codec);

    //日志系统
    Log4Qt::Logger::rootLogger()->removeAllAppenders();
    Log4Qt::Logger::rootLogger()->setLevel(Log4Qt::Level::ALL_INT);
    Log4Qt::LogManager::setHandleQtMessages(true);
    //控制台日志
    Log4Qt::PatternLayout *consoleLayout = new Log4Qt::PatternLayout();
    consoleLayout->setConversionPattern(Log4Qt::PatternLayout::TTCC_CONVERSION_PATTERN);
    consoleLayout->setConversionPattern("%d{yyyy-MM-dd HH:mm:ss:zzz} [%p] %m%n");
    consoleLayout->activateOptions();
    Log4Qt::ConsoleAppender *consoleAppender = new Log4Qt::ConsoleAppender(consoleLayout, Log4Qt::ConsoleAppender::STDOUT_TARGET);
    consoleAppender->activateOptions();
    Log4Qt::Logger::rootLogger()->addAppender(consoleAppender);
    //文件日志
    Log4Qt::PatternLayout *filelayout = new Log4Qt::PatternLayout();
    filelayout->setConversionPattern("%d{yyyy-MM-dd HH:mm:ss:zzz} [%p] %m%n");
    filelayout->activateOptions();
    Log4Qt::DailyRollingFileAppender *fileappender = new Log4Qt::DailyRollingFileAppender();
    fileappender->setName("ctkcreator");
    fileappender->setAppendFile(true);
    fileappender->setFile("ctkcreator.log");
    fileappender->setLayout(filelayout);
    fileappender->activateOptions();
    Log4Qt::Logger::rootLogger()->addAppender(fileappender);

    //启动框架
    QString path = QCoreApplication::applicationDirPath() + "/plugins";
    ctkPluginFrameworkLauncher::addSearchPath(path,true);
    ctkProperties properties;
    properties.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
    ctkPluginFrameworkFactory fwFactory(properties);
    QSharedPointer<ctkPluginFramework> framework = fwFactory.getFramework();
    try {
        framework->init();
        framework->start();
    } catch (const ctkPluginException& exc) {
        qCritical() << QLatin1String("插件框架启动失败。") << exc;
        return -1;
    }

    //安装插件
    //获取插件上下文
    ctkPluginContext* pluginContext = framework->getPluginContext();
    QStringList libFilter;

    //安装插件
    //平台判断
#if defined(Q_OS_WIN)
    libFilter << "*.dll";
#elif defined(Q_OS_LINUX)
    libFilter << "*.so";
#elif defined(Q_OS_MAC)
    libFilter << "*.dylib";
#endif
    QDirIterator dirIter(path, libFilter, QDir::Files);
    QString fileLocation;
    while(dirIter.hasNext()) {
        try {
            fileLocation = dirIter.next();
            qDebug() << "1.安装插件：" << fileLocation;
            pluginContext->installPlugin(QUrl::fromLocalFile(fileLocation));
        }
        catch (const ctkPluginException& exc) {
            qCritical() << Q_FUNC_INFO << fileLocation << exc.what();
            return -1;
        }
    }

    //启动插件
    foreach (const QSharedPointer<ctkPlugin> &plugin, pluginContext->getPlugins()) {
        try {
            QHash<QString, QString> headers = plugin->getHeaders();
            qDebug() << "2.启动插件，清单信息:" << headers;
            plugin->start();
        }
        catch (const ctkPluginException& exc) {
            qCritical() << exc.what();
            return -1;
        }
    }

    return a.exec();
}
